/*
 * COPYRIGHT. ShenZhen JiMi Technology Co., Ltd. 2020.
 * ALL RIGHTS RESERVED.
 *
 * No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
 * on any form or by any means, electronic, mechanical, photocopying, recording, 
 * or otherwise, without the prior written permission of ShenZhen JiMi Network Technology Co., Ltd.
 *
 * Amendment History:
 * 
 * Date                   By              Description
 * -------------------    -----------     -------------------------------------------
 * 2020年2月18日    Zhao Haiming         Create the class
 * http://www.jimilab.com/
*/

package com.futuremap.ws.server;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.futuremap.ws.handler.WebSocketServerHandler;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @FileName WebSocketServer.java
 * @Description: 
 *
 * @Date 2020年2月18日 下午5:26:22
 * @author Zhao Haiming
 * @version 1.0
 */
@Component
public class WebSocketServer {
	
	private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
	
	@Resource
	private WebSocketServerHandler webSocketServerHandler;
	
    public void run(int port) throws Exception {
	    EventLoopGroup bossGroup = new NioEventLoopGroup();
	    EventLoopGroup workerGroup = new NioEventLoopGroup();
	    ServerBootstrap b = new ServerBootstrap();
	    b.group(bossGroup, workerGroup)
	        .channel(NioServerSocketChannel.class)
	        .childHandler(new ChannelInitializer<SocketChannel>() {
	            @Override
	            protected void initChannel(SocketChannel ch) throws Exception {
	                ChannelPipeline pipeline = ch.pipeline();
	                pipeline.addLast("http-codec", new HttpServerCodec());
	                pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
	                ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
	                pipeline.addLast("handler", webSocketServerHandler);
	            }
	     });
	
	    Channel ch = b.bind(port).sync().channel();
	    log.info("Web socket server started at port " + port + '.');
	    log.info("Open your browser and navigate to http://localhost:" + port + '/');
	
	    ch.closeFuture().sync();
	    bossGroup.shutdownGracefully();
	    workerGroup.shutdownGracefully();
    }

    public static void main(String[] args) throws Exception {
        new WebSocketServer().run(8765);
    }
}